#ifndef GAMEPANEL_H
#define GAMEPANEL_H

#include <QLabel>
#include <QMainWindow>
#include <QMap>
#include "CardPanel.h"
#include "GameControl.h"
#include "AnimationWindow.h"
#include "EndingPanel.h"
#include <QPropertyAnimation>
#include "CountDown.h"
#include "BGMContrl.h"

QT_BEGIN_NAMESPACE
namespace Ui {
class GamePanel;
}
QT_END_NAMESPACE

class GamePanel : public QMainWindow
{
    Q_OBJECT

public:
    GamePanel(QWidget *parent = nullptr);
    ~GamePanel();
    enum AnimationType{
        ShunZi,
        LianDui,
        Plane,
        JokerBomb,
        Bomb,
        Bet
    };
    //初始化游戏控制类
    void gameControlInit();
    //更新分数面板分数
    void updatePlayerScore();
    //切割并存储图片、裁剪正常花色的图片函数
    void initCardMap();
    void cropImage(QPixmap& pix, int x, int y,Card& card);
    //初始化游戏按钮
    void initButtonGroup();
    //初始化玩家在窗口中的上下文环境
    void initPlayerContext();
    //初始化游戏场景
    void initGameScene();
    //处理游戏的状态
    void gameStatusPreces(GameControl::GameStatus status);
    //发牌
    void startDispatchCard();
    //设置移动的扑克牌步长
    void cardMoveStep(Player* player, int curPos);
    //处理发到的牌（设置所有者以便更新显示）
    void disposCard(Player* player, const Cards& cards);
    //更新扑克牌在窗口中的显示（所有者已经确认）
    void updatePlayerCards(Player* player);
    //定时器的处理动作(开启定时器后发牌动作)
    void onDiapatchCard();
    //处理玩家状态的改变
    void onPlayerStatusChanged(Player* player, GameControl::PlayerStatus status);
    //处理玩家抢地主
    void onGrabLordBet(Player* player, int bet, bool flag);
    //显示特效动画
    void showAnimation(AnimationType type, int bet = 0);
    //处理玩家的出牌
    void onDisposePlayHand(Player* player, Cards& cards);
    //隐藏玩家打出的牌
    void hidePlayerDropCards(Player* player);
    //加载玩家头像函数
    QPixmap loadRoleImage(Player::Sex sex, Player::Direction direct, Player::Role role);
    //处理玩家选牌
    void onCardSelected(Qt::MouseButton button);
    //处理玩家出牌
    void onUserPlayHand();
    //处理玩家跳过
    void onUserPass();
    //显示玩家的最终得分
    void showEndingScorePanel();
    //初始化闹钟窗口类
    void initCountDown();

protected:
    void paintEvent(QPaintEvent* event);
    void mouseMoveEvent(QMouseEvent* event);

private:
    enum CardAlign{ Horizontal, Vertical};
    struct PlayerContext{
        //1. 玩家扑克牌显示的区域
        QRect cardRect;
        //2. 出牌的区域
        QRect playHandRect;
        //3. 扑克牌的对齐方式（水平或垂直）
        CardAlign align;
        //4. 扑克牌显示正面还是背面
        bool isFrontSide;
        //5. 游戏过程中的提示信息，比如：不出
        QLabel* info;
        //6. 玩家的头像
        QLabel* roleImg;
        //7. 玩家刚打出的牌
        Cards lastCards;
    };
    Ui::GamePanel *ui;
    QPixmap m_bkImage;
    GameControl* m_gameCtl;//游戏控制类
    QVector<Player*> m_playerList;//存储游戏控制类中的三个玩家的实例
    QMap<Card, CardPanel*> m_cardMap;//存储每张牌和对应的窗口
    QSize m_cardSize;//扑克牌图片的大小信息
    QPixmap m_cardBackImg;//扑克牌背面
    QMap<Player*,PlayerContext> m_contextMap;//存储上下文的映射
    CardPanel* m_baseCard;//界面中央显示的牌
    QPoint m_baseCardPos;//界面中央显示的牌的位置
    CardPanel* m_moveCard;//移动效果的牌
    QVector<CardPanel*> m_last3Card;//最后的三张地主牌
    GameControl::GameStatus m_gameStatus;//记录当前的游戏状态
    QTimer* m_timer;
    AnimationWindow* m_animation;
    CardPanel* m_curSelCard;//保存当前用户选中的牌
    QSet<CardPanel*> m_selectCard;//保存选中的所有牌
    QRect m_cardRect;//存储剩余牌的矩形区域
    QHash<CardPanel*, QRect> m_userCards;
    CountDown* m_countDown;
    BGMContrl* m_bgm;
};
#endif // GAMEPANEL_H
